/* 
    WhaleSpotter
    Copyright (C) 2007  Bob Mottram
    fuzzgun@gmail.com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace whalespotter
{
    public class sighting
    {
        public whale individual;

        public String Observer;               // who made this sighting
        public float lattitude;               // lattitude of the sighting
        public float longitude;               // longitude of the sighting
        public float heading;                 // heading of the sighting
        public DateTime date = DateTime.Now;  //date of the sighting
        public String ImageFilename;
        public String TailFilename;
        public bool useForIdentification;
        public String Notes;

        // manually selected points
        public ArrayList manual_points;

        // an index which can be used to quickly find similar individuals
        public Byte[] Index;

        // average texture of the tail
        public int Texture;

        // features seen
        public ArrayList keyFeatures;
        public ArrayList linearFeatures;
        public ArrayList linearFeaturesAll;

        /// <summary>
        /// clear matches between features
        /// </summary>
        public void clearMatches()
        {
            for (int i = 0; i < keyFeatures.Count; i++)
            {
                tailPoint pt = (tailPoint)keyFeatures[i];
                pt.matched = false;
            }
        }

        /// <summary>
        /// save sighting to file
        /// </summary>
        /// <param name="binfile"></param>
        public void Save(BinaryWriter binfile)
        {
            binfile.Write(Observer);
            binfile.Write(lattitude);
            binfile.Write(longitude);
            binfile.Write(heading);
            binfile.Write(date.ToString());
            binfile.Write(ImageFilename);
            binfile.Write(TailFilename);
            binfile.Write(useForIdentification);
            binfile.Write(Notes);

            for (int i = 0; i < 20*2; i++)
                binfile.Write(Index[i]);

            binfile.Write(keyFeatures.Count);
            for (int i = 0; i < keyFeatures.Count; i++)
            {
                tailPoint pt = (tailPoint)keyFeatures[i];
                pt.Save(binfile);
            }

            binfile.Write(linearFeatures.Count);
            for (int i = 0; i < linearFeatures.Count; i++)
            {
                ArrayList lf = (ArrayList)linearFeatures[i];
                binfile.Write(lf.Count);
                for (int j = 0; j < lf.Count; j++)
                {
                    tailPoint pt = (tailPoint)lf[j];
                    pt.Save(binfile);
                }
            }

            if (manual_points != null)
            {
                binfile.Write(manual_points.Count);
                for (int i = 0; i < manual_points.Count; i++)
                {
                    tailPoint pt = (tailPoint)manual_points[i];
                    binfile.Write(pt.x);
                    binfile.Write(pt.y);
                }
            }
            else binfile.Write((int)0);
        }

        /// <summary>
        /// load a sighting from file
        /// </summary>
        /// <param name="binfile"></param>
        public void Load(BinaryReader binfile)
        {
            Observer = binfile.ReadString();
            lattitude = binfile.ReadSingle();
            longitude = binfile.ReadSingle();
            heading = binfile.ReadSingle();
            date = DateTime.Parse(binfile.ReadString());
            ImageFilename = binfile.ReadString();
            TailFilename = binfile.ReadString();
            useForIdentification = binfile.ReadBoolean();
            Notes = binfile.ReadString();

            Index = new Byte[20 * 2];
            for (int i = 0; i < 20 * 2; i++)
                Index[i] = binfile.ReadByte();

            keyFeatures = new ArrayList();
            int no_of_key_features = binfile.ReadInt32();
            for (int i = 0; i < no_of_key_features; i++)
            {
                tailPoint pt = new tailPoint(0,0);
                pt.Load(binfile);
                keyFeatures.Add(pt);
            }

            linearFeatures = new ArrayList();
            linearFeaturesAll = new ArrayList();
            int no_of_linear_features = binfile.ReadInt32();
            for (int i = 0; i < no_of_linear_features; i++)
            {
                ArrayList lf = new ArrayList();
                int length = binfile.ReadInt32();
                for (int j = 0; j < length; j++)
                {
                    tailPoint pt = new tailPoint(0,0);
                    pt.Load(binfile);
                    lf.Add(pt);
                    linearFeaturesAll.Add(pt);
                }
                linearFeatures.Add(lf);
            }

            int no_of_manual_points = binfile.ReadInt32();
            manual_points = new ArrayList();
            for (int i = 0; i < no_of_manual_points; i++)
            {
                int x = binfile.ReadInt32();
                int y = binfile.ReadInt32();
                tailPoint pt = new tailPoint(x, y);
                manual_points.Add(pt);
            }
        }

    }
}
